package com.tanhua.server.serivce;
import com.google.common.collect.Lists;
import java.util.*;


import com.tanhua.domain.db.*;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.*;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

@Service
public class SoulService {

    @Reference
    private SoulApi soulApi;
    @Reference
    private QuestionUserLockApi questionUserLockApi;
    @Reference
    private QuestionnaireResultApi questionnaireResultApi;
    @Reference
    private QuestionnaireReportApi questionnaireReportApi;
    @Reference
    private UserInfoApi userInfoApi;

    /**
     * 测灵魂-问卷列表
     */
    public ResponseEntity<Object> soulQuestionnaireList() {
        // 1. 获取用户id
        Long userId = UserHolder.getUserId();

        // 2. 创建最终要封装的数据对象集合
        List<QuestionnaireVo> questionnaireVoList = new ArrayList<>();

        // 3. 第一步： 我需要从用户对应的锁住表的状态查询表和锁住状态
        List<QuestionUserLock> questionUserLockList = questionUserLockApi.findByUserId(userId);
        // 3.1 判断如果为空，就需要从数据库中插入问卷列表和锁状态
        if(questionUserLockList == null || questionUserLockList.size() == 0) {
            // 3.2 查询出有多少个问卷列表
            List<Questionnaire> questionnaireList = soulApi.findQuestionnaires();
            if(questionnaireList== null) {
                return ResponseEntity.status(500).body(ErrorResult.error());
            }
            for (Questionnaire questionnaire : questionnaireList) {
                // 封装用户列表锁状态
                QuestionUserLock questionUserLock = new QuestionUserLock();
                questionUserLock.setUserId(userId);
                questionUserLock.setQuestionnaireId(questionnaire.getId());
                questionUserLock.setLevel(questionnaire.getLevel());
                // 首先这里没有数据要添加的话，默认第一等级的话是0未锁住
                if (questionnaire.getLevel() > 1) {
                    questionUserLock.setIsLock(1);
                } else {
                    questionUserLock.setIsLock(0);
                }
                // 这里少了一步，还需要添加到数据库中呢。。。。。
                questionUserLockApi.save(questionUserLock);
                // 添加进来
                questionUserLockList.add(questionUserLock);
            }
        }

        // 3.2 到这一步，我的用户对应的锁状态的表也有，然后就是查找表，并封装进去
        // 遍历封装数据
        for (QuestionUserLock questionUserLock : questionUserLockList) {
            // 3.3 封装返回的vo的数据
            QuestionnaireVo questionnaireVo = new QuestionnaireVo();
            // 先设置锁状态
            questionnaireVo.setIsLock(questionUserLock.getIsLock());
            // 3.4 通过问卷id查找问卷
            Questionnaire questionnaire = soulApi.findQuestionnaireById(questionUserLock.getQuestionnaireId());
            // 3.5 封装问卷表的信息
            BeanUtils.copyProperties(questionnaire, questionnaireVo);

            // 3.6 查询出问卷的具体的详细题目及选项
            // 创建封装问卷的题目及选项
            List<SoulQuestionVo> soulQuestionVoList = new ArrayList<>();
            // 获取问卷题干
            List<SoulQuestion> soulQuestionList = soulApi.findSoulQuestionByQuestionnaireId(questionUserLock.getQuestionnaireId());
            // 3.7 判断问卷是否存在，并获取问卷的选项
            if(soulQuestionList  != null && soulQuestionList.size() > 0) {
                for (SoulQuestion soulQuestion : soulQuestionList) {
                    List<SoulQuestionOptionVo> soulQuestionOptionVoList = new ArrayList<>();
                    // 获取问卷的选项
                    List<SoulQuestionOption> soulQuestionOptionList = soulApi.findSoulQuestionOptionById(soulQuestion.getId());
                    if(soulQuestionOptionList != null && soulQuestionOptionList.size() > 0) {
                        for (SoulQuestionOption soulQuestionOption : soulQuestionOptionList) {
                            SoulQuestionOptionVo soulQuestionOptionVo = new SoulQuestionOptionVo();
                            soulQuestionOptionVo.setId(soulQuestionOption.getId().toString());
                            soulQuestionOptionVo.setOption(soulQuestionOption.getContent());
                            soulQuestionOptionVoList.add(soulQuestionOptionVo);
                        }
                    }

                    // 到这里的话，一个题目的选项封装完了， 再封装返回的题干
                    SoulQuestionVo soulQuestionVo = new SoulQuestionVo();
                    soulQuestionVo.setId(soulQuestion.getId().toString());
                    BeanUtils.copyProperties(soulQuestion, soulQuestionVo);
                    soulQuestionVo.setOptions(soulQuestionOptionVoList);
                    soulQuestionVoList.add(soulQuestionVo);
                }
            }
            questionnaireVo.setQuestions(soulQuestionVoList);
            questionnaireVo.setId(questionUserLock.getQuestionnaireId().toString());
            if(questionnaire.getLevel() == 1) {
                questionnaireVo.setLevel("初级");
            }else if(questionnaire.getLevel() == 2){
                questionnaireVo.setLevel("中级");
            }else if(questionnaire.getLevel() == 3){
                questionnaireVo.setLevel("高级");
            }
            // 查询是否有id报告
            QuestionnaireReport questionnaireReport = questionnaireReportApi.findByQuestionnaireId(
                    userId, questionUserLock.getQuestionnaireId());
            if(questionnaireReport != null) {
                questionnaireVo.setReportId(questionnaireReport.getId().toString());
            }
            questionnaireVoList.add(questionnaireVo);
        }

        return ResponseEntity.ok(questionnaireVoList);
    }

    /**
     * 测灵魂--提交问卷
     */
    public ResponseEntity<Object> answerQuestionnaire(List<Answer> answerList) {
        // 1. 测灵魂 还需要得到分数
        Long score = 0l;
        // 1.1 因为无论得到那个问卷id 都是当前这个试题的。
        Long questionId = 0L;

        // 2. 查询分数并进行添加分数
        if(answerList == null) {
            return ResponseEntity.status(500).body(ErrorResult.error());
        }
        // 2.1 遍历
        for (Answer answer : answerList) {
            Long optionId = Long.parseLong(answer.getOptionId());
            questionId = Long.parseLong(answer.getQuestionId());

            // 查询对应的分数
            Long optionScore = soulApi.findScoreById(optionId, questionId);
            // 加好分数
            score +=  optionScore;
        }
        System.out.println("得到的分数是： = " + score);
        System.out.println("questionId：" + questionId);

        // 3. 因为我要得到问卷当前的等级，并进行解锁下一等级的试卷。不管多少张
        // 3.1 当前只有试卷的编号 --> 所以先找到当前编号的试卷 --> 然后得到问卷的id --> 就能得到当前的等级。
        SoulQuestion soulQuestion = soulApi.findSoulQuestionById(questionId);
        // 获取问卷的id
        Long questionnaireId = soulQuestion.getQuestionnaireId();
        QuestionUserLock questionUserLock = questionUserLockApi.findByQuestionnaireId(questionnaireId, UserHolder.getUserId());
        Integer level = questionUserLock.getLevel();
        // 3.2 设置当前用户的下一等级的问卷解锁状态
        questionUserLockApi.updateLock(level, UserHolder.getUserId());

        // 4. 到这里，下一等级的问卷已经解锁了，现在就是封装到报告表中和结果。
        //  我们已经计算了自己分数，然后通过分数的总分在哪个区间，并把数据都添加到报告表里
        // 4.1 查询出结果集表
        List<QuestionnaireResult> questionnaireResultList = questionnaireResultApi.findByQuestionnaireId(questionnaireId);

        // 4.2 封装报告的结果
        QuestionnaireReport questionnaireReport = new QuestionnaireReport();
        questionnaireReport.setUserId(UserHolder.getUserId());
        questionnaireReport.setQuestionnaireId(questionnaireId);
        // 4.3 封装分数得到结果的id
        for (QuestionnaireResult questionnaireResult : questionnaireResultList) {
            String[] split = questionnaireResult.getScope().split(",");
            if (score >= Integer.valueOf(split[0]) && score <= Integer.valueOf(split[1])) {
                questionnaireReport.setResultId(questionnaireResult.getId());
                System.out.println("questionnaireReport.getResultId() = " + questionnaireReport.getResultId());
                break;
            }
        }
        // 4.4 计算维度并封装维度
        Map<String, String> dimensions = dimensions(score);
        questionnaireReport.setExtroversion(dimensions.get("extroversion"));
        questionnaireReport.setJudgement(dimensions.get("judgement"));
        questionnaireReport.setAbstraction(dimensions.get("abstraction"));
        questionnaireReport.setRationality(dimensions.get("rationality"));

        // 4.5 执行添加到报告表中。
        // 先判断是否有这个试卷题的报告表了，有就执行修改，没有就添加
        QuestionnaireReport report = questionnaireReportApi.findByQuestionnaireId(UserHolder.getUserId(), questionnaireId);
        Long reportId = 0l;
        if(report != null) {
            questionnaireReport.setId(report.getId());
            questionnaireReportApi.update(questionnaireReport);
            reportId = report.getId();

        }else {
            reportId = questionnaireReportApi.save(questionnaireReport);
        }
        return ResponseEntity.ok(reportId.toString());
    }

    /**
     * 通过分数来随机得到维度值
     */
    private Map<String, String> dimensions(Long score){
        Map<String, String> map = new HashMap<>();
        String extroversion = "";
        String judgement = "";
        String abstraction = "";
        String rationality = "";
        if(score <= 20) {
            extroversion = getRandom(60, 95);
            judgement = getRandom(60, 95);
            abstraction = getRandom(60, 95);
            rationality = getRandom(60, 95);
        }else if(score <= 40) {
            extroversion = getRandom(70, 95);
            judgement = getRandom(70, 95);
            abstraction = getRandom(70, 95);
            rationality = getRandom(70, 95);
        }else if(score <= 55) {
            extroversion = getRandom(80, 95);
            judgement = getRandom(80, 95);
            abstraction = getRandom(80, 95);
            rationality = getRandom(80, 95);
        }else {
            extroversion = getRandom(85, 96);
            judgement = getRandom(85, 96);
            abstraction = getRandom(85, 96);
            rationality = getRandom(85, 96);
        }
        map.put("extroversion", extroversion);
        map.put("judgement", judgement);
        map.put("abstraction", abstraction);
        map.put("rationality", rationality);
        return map;
    }

    // 得到随机区间的数
    private String getRandom(int num1, int num2){
        // 60-95 num1 : 60 num2 : 95
        int random = (int)(Math.random() * (num2 - num1) +  num1);
        return random + "%";
    }

    /**
     * 接口名称：测灵魂-查看结果
     */
    public ResponseEntity<Object> findQuestionnaireReport(Long reportId) {
        // 1. 获取用户id
        Long userId = UserHolder.getUserId();

        // 2. 封装返回数据的结果
        SoulReportVo soulReportVo = new SoulReportVo();

        // 3. 通过报告的Id查出结果的id，并再查出封面和结果封装到vo中。
        // 3.1 查找报告
        QuestionnaireReport questionnaireReport = questionnaireReportApi.findById(reportId);
        if(questionnaireReport == null) {
            return ResponseEntity.status(500).body(ErrorResult.noReportError());
        }
        // 3.2 查找结果
        QuestionnaireResult questionnaireResult = questionnaireResultApi.findById(questionnaireReport.getResultId());
        if(questionnaireResult == null) {
            return ResponseEntity.status(500).body(ErrorResult.noReportError());
        }
        // 3.3 封装结果和图片
        soulReportVo.setConclusion(questionnaireResult.getContent());
        soulReportVo.setCover(questionnaireResult.getCover());
        // 3.4 封装维度信息
        List<Dimensions> dimensionList = new ArrayList<>();
        // 外向,判断,抽象,理性
        dimensionList.add(new Dimensions("外向",questionnaireReport.getExtroversion()));
        dimensionList.add(new Dimensions("判断",questionnaireReport.getJudgement()));
        dimensionList.add(new Dimensions("抽象",questionnaireReport.getAbstraction()));
        dimensionList.add(new Dimensions("理性",questionnaireReport.getRationality()));
        soulReportVo.setDimensions(dimensionList);

        // 3.5 封装与用户相似的用户， 如果没有，就默认给5个数据
        List<SimilarYou> similarYouList = new ArrayList<>();
        // 3.5.1 查找相同的结果id，去寻找到对应结果集
        List<QuestionnaireReport> questionnaireReportList = questionnaireReportApi.findListByResultId(questionnaireReport.getResultId());
        // 3.5.2 当前用户的信息
        UserInfo userInfo = userInfoApi.findById(userId);
        if(questionnaireReportList == null || questionnaireReportList.size() <= 1) {
            // 如果找不到数据或者只有包含了自己的话， 默认给几个数据
            // 而且是异性的推荐的用户, 查找异性用户的集合
            List<UserInfo> userInfoList = userInfoApi.findByGender(userInfo.getGender());
            if(userInfoList != null ) {
                if(userInfoList.size() > 7){
                    for (int i = 0; i < 7; i++) {
                        UserInfo info = userInfoList.get(i);
                        // 排查自己的id
                        if(info.getId() == userId) continue;
                        similarYouList.add(new SimilarYou(info.getId(),info.getAvatar()));
                    }
                }else {
                    for (UserInfo info : userInfoList) {
                        // 排查自己的id
                        if(info.getId() == userId) continue;
                        similarYouList.add(new SimilarYou(info.getId(),info.getAvatar()));
                    }
                }

            }
        }else {
            for (QuestionnaireReport report : questionnaireReportList) {
                if(report.getUserId() == userId) continue; // 排除自己
                UserInfo info = userInfoApi.findById(report.getUserId());
                if(info.getGender().equals(userInfo.getGender())) continue; // 排除同性
                similarYouList.add(new SimilarYou(info.getId(),info.getAvatar()));
            }
            if(similarYouList == null || similarYouList.size() < 3) {
                List<UserInfo> userInfoList = userInfoApi.findByGender(userInfo.getGender());
                if(userInfoList != null ) {
                    if(userInfoList.size() > 7){
                        for (int i = 0; i < 7; i++) {
                            UserInfo info = userInfoList.get(i);
                            // 排查自己的id
                            if(info.getId() == userId) continue;
                            similarYouList.add(new SimilarYou(info.getId(),info.getAvatar()));
                        }
                    }else {
                        for (UserInfo info : userInfoList) {
                            // 排查自己的id
                            if(info.getId() == userId) continue;
                            similarYouList.add(new SimilarYou(info.getId(),info.getAvatar()));
                        }
                    }

                }
            }
        }
        soulReportVo.setSimilarYou(similarYouList);

        // 4. 返回结果。
        return ResponseEntity.ok(soulReportVo);
    }
}
